文章同步發表至 Medium
有了 API 可以取得資料之後,接下來要使用 Leaflet 來把結果渲染出來。
Leaflet 的使用邏輯很簡單:
就像一開始提到的動詞——渲染,要使用 Leaflet 前必須準備一個空間讓他發揮,於是我們建立一個空白的 div
,也別忘記先把 css
js
檔案的 CDN 掛載上去:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>旅遊規劃</title>
<!-- Leaflet 的 CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css"
integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
crossorigin=""/>
<style>
/* 設定高度給 Leaflet 使用 */
body{
height: 98vh;
}
/* 設定高度給 Leaflet 使用 */
#app, #map{
height: 100%;
}
</style>
</head>
<body>
<!-- 搭配前端套件 Vue3 使用,所以另外建立一個 #app -->
<div id="app">
<!-- 實際上放置 Leaflet 的地方 -->
<div id="map"></div>
</div>
<!-- LEaflet 本體 -->
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"
integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
crossorigin=""></script>
<!-- Axios(選用) -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Vue3(選用) -->
<script src="https://unpkg.com/vue@3"></script>
</body>
</html>
接著要來初始化地圖:
<!DOCTYPE html>
<html lang="en">
<body>
<!-- 前略 -->
<script>
const app = Vue.createApp({
data(){},
methods:{
initMap(data){
// 初始化地圖
// 'map' 中放入指定渲染節點的 id
// setView([lat,lon]) 放入預設載入的中心位置
let map = L.map('map').setView([24.175339, 120.648586], 19);
// 新增 OSM 的圖磚
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
},
getScenicSpots(){
// 取得景點資料
axios({
method: 'get',
url: './api/ScenicSpot'
}).then(res => {
this.initMap(res.data);
}).catch(err => {
console.log(err);
})
},
},
mounted(){
// Vue 掛載之後執行
this.getScenicSpots();
}
});
app.mount('#app');
</script>
</body>
</html>
成功載入的話會看到以逢甲附近為中心點的地圖,可以隨意縮放移動。
新增點位的方式很簡單,在載入圖磚之後把所有座標都利用 marker()
來建立成一個圖層之後,附加到原本的 map 上即可:
initMap(data){
// 設定地圖
let map = L.map('map').setView([24.175339, 120.648586], 19);
// 新增圖磚
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
// 建立點位
let layer = data.map(ele => { L.marker([ele.y, ele.x]).addTo(map) });
// 新增點位到圖磚上
map.addLayer(layer);
}
成功執行的話,會看到原本地圖靠近中間底部的地方有一個點,他就是我們渲染出來的景點之一:
這個時候如果你努力的滾滑鼠滾輪,用力的把他們縮小,你會發現你的網頁變的很卡,然後密集恐懼症開始發作:
這種顯示方式太不優雅了!所以我們要利用 Leaflet 的套件——Leaflet.markercluster 來優化一下網頁的呈現。
Cluster 翻譯為叢集,這個套件的目的是讓我們把地圖縮小到一定比例的時候,幫助我們把多個目標合併成一個點,看起來會比較舒適,效果如下圖:
initMap(data){
let map = L.map('map').setView([24.175339, 120.648586], 19);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
// 原始
// let coor = data.map(ele => { L.marker([ele.y, ele.x]).addTo(map) });
// map.addLayer(coor);
// Cluster
let markers = L.markerClusterGroup();
data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
map.addLayer(markers);
}
以下是縮放到不同尺寸的樣子:
可以看到預設就會有不同顏色代表不同數量的呈現,並且移動到 cluster 上方還會很貼心的幫你標示出這個 cluster 所代表的區域,點擊之後會自動幫你 zoom in ?
當然顏色、標示這些功能都可以做調整,只是我會著墨在後端比較多,因此這篇文章只會介紹到這裡,其餘功能如果摸索上有問題,也歡迎留言一起討論喔。